home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 23
/
AACD 23.iso
/
AACD
/
Programming
/
tek
/
examples
/
kine
/
mathutil.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-05-26
|
12KB
|
645 lines
/*
*
* Math Funktions
* Frank Pagels Defect Softworks 2001
*
*
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "mathutil.h"
#include <stdlib.h>
#ifndef PI
#ifdef M_PI
#define PI M_PI
#else
#define PI 3.1415927
#endif
#endif
#define CM_0 OF_11
#define CM_1 OF_12
#define CM_2 OF_13
#define CM_3 OF_21
#define CM_4 OF_22
#define CM_5 OF_23
#define CM_6 OF_31
#define CM_7 OF_32
#define CM_8 OF_33
/*
** Computes the determinant of the upper 3x3 submatrix block
** of the supplied matrix
*/
TFLOAT Determinant(Matrix *pA)
{
#define a(x) (pA->v[CM_##x])
return ( a(0)*a(4)*a(8) + a(1)*a(5)*a(6) + a(2)*a(3)*a(7)
- a(0)*a(5)*a(7) - a(1)*a(3)*a(8) - a(2)*a(4)*a(6));
#undef a
}
/*
** Builds the inverse of the upper 3x3 submatrix block of the
** supplied matrix for the backtransformation of the normals
*/
void DoInvert(Matrix *pA, Matrix *pB)
{
TFLOAT det = 1.0 / Determinant(pA);
#define a(x) (pA->v[CM_##x])
#define b(x) (pB->v[CM_##x])
b(0) = (TFLOAT)(a(4)*a(8) - a(5)*a(7))*det;
b(1) = (TFLOAT)(a(2)*a(7) - a(1)*a(8))*det;
b(2) = (TFLOAT)(a(1)*a(5) - a(2)*a(4))*det;
b(3) = (TFLOAT)(a(5)*a(6) - a(3)*a(8))*det;
b(4) = (TFLOAT)(a(0)*a(8) - a(2)*a(6))*det;
b(5) = (TFLOAT)(a(2)*a(3) - a(0)*a(5))*det;
b(6) = (TFLOAT)(a(3)*a(7) - a(4)*a(6))*det;
b(7) = (TFLOAT)(a(1)*a(6) - a(0)*a(7))*det;
b(8) = (TFLOAT)(a(0)*a(4) - a(1)*a(3))*det;
#undef a
#undef b
}
/*
**
** Simple Matrixmultiplikation
** A * B = C
**
*/
void MatMultGeneral(Matrix *pA, Matrix *pB, Matrix *pC)
{
#define a(x) (pA->v[OF_##x])
#define b(x) (pB->v[OF_##x])
#define c(x) (pC->v[OF_##x])
c(11) = a(11)*b(11)+a(12)*b(21)+a(13)*b(31)+a(14)*b(41);
c(12) = a(11)*b(12)+a(12)*b(22)+a(13)*b(32)+a(14)*b(42);
c(13) = a(11)*b(13)+a(12)*b(23)+a(13)*b(33)+a(14)*b(43);
c(14) = a(11)*b(14)+a(12)*b(24)+a(13)*b(34)+a(14)*b(44);
c(21) = a(21)*b(11)+a(22)*b(21)+a(23)*b(31)+a(24)*b(41);
c(22) = a(21)*b(12)+a(22)*b(22)+a(23)*b(32)+a(24)*b(42);
c(23) = a(21)*b(13)+a(22)*b(23)+a(23)*b(33)+a(24)*b(43);
c(24) = a(21)*b(14)+a(22)*b(24)+a(23)*b(34)+a(24)*b(44);
c(31) = a(31)*b(11)+a(32)*b(21)+a(33)*b(31)+a(34)*b(41);
c(32) = a(31)*b(12)+a(32)*b(22)+a(33)*b(32)+a(34)*b(42);
c(33) = a(31)*b(13)+a(32)*b(23)+a(33)*b(33)+a(34)*b(43);
c(34) = a(31)*b(14)+a(32)*b(24)+a(33)*b(34)+a(34)*b(44);
c(41) = a(41)*b(11)+a(42)*b(21)+a(43)*b(31)+a(44)*b(41);
c(42) = a(41)*b(12)+a(42)*b(22)+a(43)*b(32)+a(44)*b(42);
c(43) = a(41)*b(13)+a(42)*b(23)+a(43)*b(33)+a(44)*b(43);
c(44) = a(41)*b(14)+a(42)*b(24)+a(43)*b(34)+a(44)*b(44);
#undef a
#undef b
#undef c
}
/*
** A * B , A=4x4 , B = 1x4
**
*/
void MatMultPoint(Matrix *pA, TFLOAT *v, TFLOAT *tmp)
{
#define a(x) (pA->v[OF_##x])
tmp[0] = a(11) * v[0] + a(12) * v[1] + a(13) * v[2] + a(14) * v[3];
tmp[1] = a(21) * v[0] + a(22) * v[1] + a(23) * v[2] + a(24) * v[3];
tmp[2] = a(31) * v[0] + a(32) * v[1] + a(33) * v[2] + a(34) * v[3];
tmp[3] = a(41) * v[0] + a(42) * v[1] + a(43) * v[2] + a(44) * v[3];
#undef a
}
/*
** Copy matrix B to matrix A
** A = B
*/
void MatCopy(Matrix *pA, Matrix *pB)
{
int i;
for (i=0; i<16; i++) pA->v[i] = pB->v[i];
pA->flags = pB->flags;
pA->Inverse = pB->Inverse;
}
void LoadMatrix(Matrix *pA, const TFLOAT *v)
{
#define a(x) pA->v[OF_##x] = *v++
a(11); a(21); a(31); a(41);
a(12); a(22); a(32); a(42);
a(13); a(23); a(33); a(43);
a(14); a(24); a(34); a(44);
//if (*(v-4) == 0.f && *(v-3) == 0.f && *(v-2) == 0.f && *(v-1) == 1.f)
// pA->flags = MGLMAT_0001;
#undef a
}
void LoadIdentity(Matrix *pA)
{
#define a(x) pA->v[OF_##x] = 0.f;
#define b(x) pA->v[OF_##x] = 1.f;
b(11); a(21); a(31); a(41);
a(12); b(22); a(32); a(42);
a(13); a(23); b(33); a(43);
a(14); a(24); a(34); b(44);
//pA->flags = MGLMAT_IDENTITY;
#undef a
#undef b
}
void PrintMatrix(Matrix *pA)
{
#define a(x) (pA->v[OF_##x])
printf("Matrix at 0x%lX\n", (TUINT)pA);
printf(" | %6.3f %6.3f %6.3f %6.3f |\n",
a(11), a(12), a(13), a(14));
printf(" | %6.3f %6.3f %6.3f %6.3f |\n",
a(21), a(22), a(23), a(24));
printf("A = | %6.3f %6.3f %6.3f %6.3f |\n",
a(31), a(32), a(33), a(34));
printf(" | %6.3f %6.3f %6.3f %6.3f |\n",
a(41), a(42), a(43), a(44));
#undef a
}
/*
** Get Hartenberg Matrix for
** Theta, d, a, alpha
**
*/
void GetHartenberg(joint *j, Matrix *pA)
{
TFLOAT ct,st,cal,sal,th,al;
#define a(x) (pA->v[OF_##x])
th = j->theta; /* * PI / 180; */
al = j->alpha; /* * PI / 180; */
ct = cos(th);
st = sin(th);
cal = cos(al);
sal = sin(al);
a(11) = ct;
a(12) = -cal*st;
a(13) = sal*st;
a(14) = j->a*ct;
a(21) = st;
a(22) = cal*ct;
a(23) = -sal*ct;
a(24) = j->a*st;
a(31) = 0;
a(32) = sal;
a(33) = cal;
a(34) = j->d;
a(41) = 0;
a(42) = 0;
a(43) = 0;
a(44) = 1;
#undef a
}
/*
**
** Subtract C = A - B
**
*/
void GenMatSub(GenMatrix *A,GenMatrix *B, GenMatrix *C)
{
TINT i,j;
for(i=0;i < A->rows;i++)
{
for(j=0;j < A->colum;j++)
{
C->m[i][j] = A->m[i][j] - B->m[i][j];
}
}
}
/*
**
** Add A + B = C
**
*/
void GenMatAdd(GenMatrix *A, GenMatrix *B, GenMatrix *C)
{
TINT i,j;
for(i=0;i < A->rows;i++)
{
for(j=0;j < A->colum;j++)
{
C->m[i][j] = A->m[i][j] + B->m[i][j];
}
}
}
/*
**
** Multiply Matrix A,B to C
**
*/
void GenMatMultiply(GenMatrix *A, GenMatrix *B, GenMatrix *C)
{
TINT i,j,k;
TFLOAT sum;
if(A->colum == B->rows)
{
for(i=0;i < A->rows;i++)
{
for(k=0; k < B->colum;k++)
{
C->m[i][k] = 0;
for(j=0;j < A->colum;j++)
{
C->m[i][k] += A->m[i][j] * B->m[j][k];
}
}
}
}
}
/*
**
** Transpose Matrix A to B
**
*/
void GenMatTranspose(GenMatrix *A, GenMatrix *B)
{
TINT i,j;
if(A->colum == B->rows)
{
if(A->rows == B->colum)
{
for(i=0;i < A->rows;i++)
{
for(j=0;j < A->colum;j++)
{
B->m[j][i] = A->m[i][j];
}
}
}
}
}
/*
**
** GenLoadIndentity
**
*/
void GenMatLoadIdentity(GenMatrix *A, TFLOAT a)
{
TINT i,j;
memset(A->m,0,A->rows*A->colum*sizeof(TFLOAT));
if(A->colum == A->rows)
{
for(i=0;i < A->rows;i++)
{
for(j=0;j < A->colum;j++)
{
if(i==j)
A->m[i][j] = a;
else
A->m[i][j] = 0;
}
}
}
}
/*
**
** Invers Matrix with Crout's Method
**
*/
void GenMatInvers1(GenMatrix *A)
{
TINT i,j,k;
TINT N = A->rows;
TFLOAT a,sum;
/* LU Decomposing with Crout's Method */
a = 1.0 / A->m[0][0];
for(j=1;j < N ;j++)
{
A->m[0][j] = A->m[0][j] * a;
}
for(j=1;j<N-1;j++)
{
i = j;
for(i;i<N ;i++)
{
sum = 0;
for(k=0;k < j;k++)
{
sum += A->m[i][k] * A->m[k][j];
}
A->m[i][j] -= sum;
}
k=j+1;
for(k;k < N;k++)
{
sum = 0;
for(i=0;i < j;i++)
{
sum += A->m[j][i] * A->m[i][k];
}
A->m[j][k] -= sum;
A->m[j][k] /= A->m[j][j];
}
}
for(k=0;k < N-1;k++)
{
sum += A->m[N-1][k] * A->m[k][N-1];
}
A->m[N-1][N-1] -= sum;
/* */
/*
for(i=1;j<=N;j++)
{
for(i=1;i<=N;i++) col[i]=0.0;
col[j]=1.0;
lubks(&A,N,indx,col);
for(i=1;i<=N,j++)
}
*/
}
/*
**
** Invert Matrix nach GemsII Rod G. Bogart
**
*/
void GenMatInvers(GenMatrix *A)
{
TINT i,j,k;
/* Locations of pivot elements */
TINT *pvt_i, *pvt_j;
TFLOAT pvt_val; /* Value of current pivot element */
TFLOAT hold; /* Temporary storage */
TFLOAT determ; /* Determinant */
determ = 1.0;
//pvt_i = (TINT *) malloc(A->rows * sizeof(TINT));
//pvt_j = (TINT *) malloc(A->rows * sizeof(TINT));
pvt_i = A->pvt_i;
pvt_j = A->pvt_j;
for (k = 0; k < A->rows; k++)
{
/* Locate k'th pivot element */
pvt_val = A->m[k][k]; /* Initialize for search */
pvt_i[k] = k;
pvt_j[k] = k;
for (i = k; i < A->rows; i++)
for (j = k; j < A->rows; j++)
if (fabs(A->m[i][j]) > fabs(pvt_val))
{
pvt_i[k] = i;
pvt_j[k] = j;
pvt_val = A->m[i][j];
}
/* Product of pivots, gives determinant when finished */
determ *= pvt_val;
if (determ == 0.0) {
/* Matrix is singular (zero determinant). */
free(pvt_i);
free(pvt_j);
return;
}
/* "Interchange" rows (with sign change stuff) */
i = pvt_i[k];
if (i != k) /* If rows are different */
for (j = 0; j < A->rows; j++)
{
hold = -A->m[k][j];
A->m[k][j] = A->m[i][j];
A->m[i][j] = hold;
}
/* "Interchange" columns */
j = pvt_j[k];
if (j != k) /* If columns are different */
for (i = 0; i < A->rows; i++)
{
hold = -A->m[i][k];
A->m[i][k] = A->m[i][j];
A->m[i][j] = hold;
}
/* Divide column by minus pivot value */
for (i = 0; i < A->rows; i++)
if (i != k) /* Don't touch the pivot entry */
A->m[i][k] /= ( -pvt_val) ; /* (Tricky C syntax for division) */
/* Reduce the matrix */
for (i = 0; i < A->rows; i++)
{
hold = A->m[i][k];
for (j = 0; j < A->rows; j++)
if ( i != k && j != k ) /* Don't touch pivot. */
A->m[i][j] += hold * A->m[k][j];
}
/* Divide row by pivot */
for (j = 0; j < A->rows; j++)
if (j != k) /* Don't touch the pivot! */
A->m[k][j] /= pvt_val;
/* Replace pivot by reciprocal (at last we can touch it). */
A->m[k][k] = 1.0/pvt_val;
}
/* That was most of the work, one final pass of row/column interchange */
/* to finish */
for (k = A->rows-2; k >= 0; k--) /* Don't need to work with 1 by 1 */
/* corner */
{
i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */
if (i != k) /* If rows are different */
for(j = 0; j < A->rows; j++)
{
hold = A->m[k][j];
A->m[k][j] = -A->m[i][j];
A->m[i][j] = hold;
}
j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */
if (j != k) /* If columns are different */
for (i = 0; i < A->rows; i++)
{
hold = A->m[i][k];
A->m[i][k] = -A->m[i][j];
A->m[i][j] = hold;
}
}
//free(pvt_i);
//free(pvt_j);
//return(determ);
}
/*
**
** Copy GenMatrix A to B
**
*/
void GenMatCopy(GenMatrix *A,GenMatrix *B)
{
TINT i,j;
for(i=0;i<A->rows;i++)
{
for(j=0;j<A->colum;j++)
{
B->m[i][j] = A->m[i][j];
}
}
}
/*
**
** Get Pseudoinverse of A
**
*/
void GenMatPseudoInvers(GenMatrix *A, GenMatrix *B, GenMatrix *C)
{
if(A->rows > A->colum)
{
GenMatTranspose(A,B);
GenMatMultiply(B,A,C);
GenMatInvers(C);
GenMatMultiply(A,C,B);
GenMatTranspose(B,A);
}
else
{
GenMatTranspose(A,B);
GenMatMultiply(A,B,C);
GenMatInvers(C);
A->rows = B->rows;
A->colum = B->colum;
GenMatMultiply(B,C,A);
}
}
/*
A = M;
if ( ROWS(M) > COLUMNS(M) )
A = TRANSPOSE(A);
B = TRANSPOSE(A) * INV( A * TRANSPOSE(A) );
if ( ROWS(M) > COLUMNS(M) )
B = TRANSPOSE(B);
*/
/*
**
** Print Matrix
**
*/
void GenPrintMatrix(GenMatrix *A)
{
TINT i,j;
for(i=0;i < A->rows;i++)
{
printf(" |");
for(j=0;j < A->colum;j++)
{
printf(" %6.3f",A->m[i][j]);
}
printf("|\n");
}
printf("\n\n");
}
void InitGenMatrix(GenMatrix *A, TINT row, TINT colum)
{
//memset(A->m,0,row*colum*sizeof(TFLOAT));
A->rows=row;
A->colum=colum;
}
void DestroyGenMatrix(GenMatrix *A)
{
A->rows = 0;
A->colum = 0;
}
void GenLoadMatrix(Matrix *pA, const TFLOAT *v)
{
}